import sqlite3
import socket, time
import threading

conn1 = sqlite3.connect('count.db')
conn2 = conn1.cursor()
conn2.execute('CREATE TABLE IdAndPassword(NAME TEXT, COUNT TEXT)')
conn1.close()
lists = []
clients = dict()

class chatServer(threading.Thread):    
    global clients    
    def __init__(self, client):
        threading.Thread.__init__(self) 
        self.client_sock, self.client_addr = client 
        clients[self.client_sock.fileno()] = self.client_sock
        self.client_sock1 = self.client_sock
        self.userName = ''
        self.debug = True 

    def responseMessage(self, sock, requestMessage):
        global lists,cur
        con = sqlite3.connect('login.db')
        cur = con.cursor()
        request_message = requestMessage.split()
        protocol = request_message[0]
        protocol_check = list(protocol)[:4]    

        if protocol == 'USER' :
            if(len(request_message) == 2):
                print('>', ' '.join(request_message))
                print('< 531 Invalid user or password')
                sendMessage = '531 Invalid user or password \r\n'
                sock.send(bytes(sendMessage, encoding='UTF-8'))
            else:
                cur.execute('SELECT * FROM IdAndPassword WHERE ID = "%s"' % request_message[1])
                if cur.fetchone() :
                    cur.execute('SELECT * FROM IdAndPassword WHERE ID = "%s"' % request_message[1])
                    if cur.fetchone()[1] == request_message[2] :
                        print('>', ' '.join(request_message))
                        print('< 230 User logged in')
                        sendMessage = '230 User logged in \r\n'
                        sock.send(bytes(sendMessage, encoding='UTF-8'))
                    else:
                        print('>', ' '.join(request_message))
                        print('< 531 Invalid user or password')
                        sendMessage = '531 Invalid user or password \r\n'
                        sock.send(bytes(sendMessage, encoding='UTF-8'))                    
                else :
                    cur.execute('INSERT INTO IdAndPassword VALUES(?, ?)', (request_message[1], request_message[2]))
                    con.commit()
                    self.userName = request_message[1]
                    print('>', ' '.join(request_message))
                    print('< 230 User logged in')
                    sendMessage = '230 User logged in \r\n'
                    sock.send(bytes(sendMessage, encoding='UTF-8'))
                    
        elif ''.join(protocol_check) == 'QUIT' :
            print('>', ' '.join(request_message))
            print('< 221 service closeing')
            sendMessage = '221 service closeing \r\n'
            sock.send(bytes(sendMessage, encoding='UTF-8'))
            del clients[self.client_sock.fileno()]
            sock.close()
            self.client_sock = ''
            
        elif ''.join(protocol_check) == 'LIST' :
            print('>', ' '.join(request_message))
            cur.execute('SELECT ID FROM IdAndPassword')
            for userid in cur.fetchall():
                lists += userid            
            lists =  ' '.join(lists)
            print('< 231 Users:', lists)
            sendMessage = '231 Users:' + lists + '\r\n'
            sock.send(bytes(sendMessage, encoding='UTF-8'))
            lists = []
                    
        elif self.userName is '':
            print('>', ' '.join(request_message))
            print('< 530 Not logged in')
            sendMessage = '530 Not logged in\r\n'
            sock.send(bytes(sendMessage, encoding='UTF-8'))   
        
        elif protocol == 'FROM' :
            print('>', ' '.join(request_message))
            print('< 299', ' '.join(request_message))
            print('< 200 OK')
            request_message.insert(0, '299')
            sendMessage = ' '.join(request_message)
            for self.client_sock1 in clients.values():
                if self.client_sock1 is not sock:
                    self.conn1fd = self.client_sock1
                    self.conn1fd.send(bytes(sendMessage, encoding='UTF-8'))
            sendMessage = '200 OK\r\n'
            sock.send(bytes(sendMessage, encoding='UTF-8'))
        
        else :
            print('>', ' '.join(request_message))
            sendMessage = '500 Syntax error \r\n'
            sock.send(bytes(sendMessage, encoding='UTF-8'))
            print('<', sendMessage)        
                
    def run(self):
        while True:
            if self.debug:
                print('Wait for readable sockets:',
                      [sockobj.fileno() for sockobj in clients.values()])
            if self.client_sock is not '':
                data = self.client_sock.recv(1024).decode()
            else:
                break
            time.sleep(1) 
            if not data: 
                sock.close()
            else:
                self.responseMessage(self.client_sock, data)

if __name__ == "__main__":    
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    sock.bind(('', 9619)) 
    sock.listen(5)
    print('Wait for readable sockets:',
                      [sockobj.fileno() for sockobj in clients.values()])
    while True: # Serve forever. 
        server = sock.accept()
        chatServer(server).start()